const authService = require('../services/authService');
const Joi = require('joi');

// 验证模式
const schemas = {
  register: Joi.object({
    email: Joi.string().email().required(),
    password: Joi.string().min(8).required(),
    firstName: Joi.string().min(1).max(50).required(),
    lastName: Joi.string().min(1).max(50).required(),
    role: Joi.string().valid('admin', 'user').default('user')
  }),
  
  login: Joi.object({
    email: Joi.string().email().required(),
    password: Joi.string().required()
  }),
  
  refreshToken: Joi.object({
    refreshToken: Joi.string().required()
  }),
  
  verifyEmail: Joi.object({
    token: Joi.string().required()
  }),
  
  forgotPassword: Joi.object({
    email: Joi.string().email().required()
  }),
  
  resetPassword: Joi.object({
    token: Joi.string().required(),
    password: Joi.string().min(8).required()
  }),
  
  changePassword: Joi.object({
    currentPassword: Joi.string().required(),
    newPassword: Joi.string().min(8).required()
  })
};

class AuthController {
  // 用户注册
  async register(request, reply) {
    try {
      const { error, value } = schemas.register.validate(request.body);
      if (error) {
        return reply.code(400).send({
          success: false,
          message: 'Validation error',
          errors: error.details.map(detail => detail.message)
        });
      }
      
      const tenantId = request.tenantId;
      if (!tenantId) {
        return reply.code(400).send({
          success: false,
          message: 'Tenant context required'
        });
      }
      
      const result = await authService.register({
        ...value,
        tenantId
      });
      
      reply.code(201).send({
        success: true,
        data: result,
        message: 'User registered successfully'
      });
      
    } catch (error) {
      request.log.error(error);
      
      if (error.message.includes('already exists')) {
        return reply.code(409).send({
          success: false,
          message: error.message
        });
      }
      
      reply.code(500).send({
        success: false,
        message: 'Registration failed'
      });
    }
  }
  
  // 用户登录
  async login(request, reply) {
    try {
      const { error, value } = schemas.login.validate(request.body);
      if (error) {
        return reply.code(400).send({
          success: false,
          message: 'Validation error',
          errors: error.details.map(detail => detail.message)
        });
      }
      
      const tenantId = request.tenantId;
      if (!tenantId) {
        return reply.code(400).send({
          success: false,
          message: 'Tenant context required'
        });
      }
      
      const result = await authService.login({
        ...value,
        tenantId,
        ipAddress: request.ip,
        userAgent: request.headers['user-agent']
      });
      
      // 设置 HTTP-only cookie 用于刷新令牌
      reply.setCookie('refreshToken', result.refreshToken, {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'strict',
        maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
      });
      
      reply.send({
        success: true,
        data: {
          user: result.user,
          accessToken: result.accessToken,
          expiresIn: result.expiresIn
        },
        message: 'Login successful'
      });
      
    } catch (error) {
      request.log.error(error);
      
      if (error.message.includes('Invalid credentials') || 
          error.message.includes('Account locked') ||
          error.message.includes('not found') ||
          error.message.includes('not verified')) {
        return reply.code(401).send({
          success: false,
          message: error.message
        });
      }
      
      reply.code(500).send({
        success: false,
        message: 'Login failed'
      });
    }
  }
  
  // 刷新访问令牌
  async refreshToken(request, reply) {
    try {
      // 从 cookie 或请求体获取刷新令牌
      const refreshToken = request.cookies.refreshToken || request.body.refreshToken;
      
      if (!refreshToken) {
        return reply.code(400).send({
          success: false,
          message: 'Refresh token required'
        });
      }
      
      const result = await authService.refreshToken(refreshToken);
      
      // 更新刷新令牌 cookie
      reply.setCookie('refreshToken', result.refreshToken, {
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production',
        sameSite: 'strict',
        maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
      });
      
      reply.send({
        success: true,
        data: {
          accessToken: result.accessToken,
          expiresIn: result.expiresIn
        },
        message: 'Token refreshed successfully'
      });
      
    } catch (error) {
      request.log.error(error);
      
      // 清除无效的刷新令牌 cookie
      reply.clearCookie('refreshToken');
      
      reply.code(401).send({
        success: false,
        message: 'Invalid refresh token'
      });
    }
  }
  
  // 验证邮箱
  async verifyEmail(request, reply) {
    try {
      const { error, value } = schemas.verifyEmail.validate(request.body);
      if (error) {
        return reply.code(400).send({
          success: false,
          message: 'Validation error',
          errors: error.details.map(detail => detail.message)
        });
      }
      
      await authService.verifyEmail(value.token);
      
      reply.send({
        success: true,
        message: 'Email verified successfully'
      });
      
    } catch (error) {
      request.log.error(error);
      
      if (error.message.includes('Invalid') || error.message.includes('expired')) {
        return reply.code(400).send({
          success: false,
          message: error.message
        });
      }
      
      reply.code(500).send({
        success: false,
        message: 'Email verification failed'
      });
    }
  }
  
  // 忘记密码
  async forgotPassword(request, reply) {
    try {
      const { error, value } = schemas.forgotPassword.validate(request.body);
      if (error) {
        return reply.code(400).send({
          success: false,
          message: 'Validation error',
          errors: error.details.map(detail => detail.message)
        });
      }
      
      const tenantId = request.tenantId;
      if (!tenantId) {
        return reply.code(400).send({
          success: false,
          message: 'Tenant context required'
        });
      }
      
      await authService.forgotPassword({
        ...value,
        tenantId
      });
      
      reply.send({
        success: true,
        message: 'Password reset email sent'
      });
      
    } catch (error) {
      request.log.error(error);
      
      // 为了安全，即使用户不存在也返回成功消息
      reply.send({
        success: true,
        message: 'Password reset email sent'
      });
    }
  }
  
  // 重置密码
  async resetPassword(request, reply) {
    try {
      const { error, value } = schemas.resetPassword.validate(request.body);
      if (error) {
        return reply.code(400).send({
          success: false,
          message: 'Validation error',
          errors: error.details.map(detail => detail.message)
        });
      }
      
      await authService.resetPassword(value.token, value.password);
      
      reply.send({
        success: true,
        message: 'Password reset successfully'
      });
      
    } catch (error) {
      request.log.error(error);
      
      if (error.message.includes('Invalid') || error.message.includes('expired')) {
        return reply.code(400).send({
          success: false,
          message: error.message
        });
      }
      
      reply.code(500).send({
        success: false,
        message: 'Password reset failed'
      });
    }
  }
  
  // 修改密码
  async changePassword(request, reply) {
    try {
      const { error, value } = schemas.changePassword.validate(request.body);
      if (error) {
        return reply.code(400).send({
          success: false,
          message: 'Validation error',
          errors: error.details.map(detail => detail.message)
        });
      }
      
      const userId = request.user.id;
      
      await authService.changePassword(
        userId,
        value.currentPassword,
        value.newPassword
      );
      
      reply.send({
        success: true,
        message: 'Password changed successfully'
      });
      
    } catch (error) {
      request.log.error(error);
      
      if (error.message.includes('Invalid current password')) {
        return reply.code(400).send({
          success: false,
          message: error.message
        });
      }
      
      reply.code(500).send({
        success: false,
        message: 'Password change failed'
      });
    }
  }
  
  // 登出
  async logout(request, reply) {
    try {
      const refreshToken = request.cookies.refreshToken;
      
      if (refreshToken) {
        await authService.logout(refreshToken);
      }
      
      // 清除刷新令牌 cookie
      reply.clearCookie('refreshToken');
      
      reply.send({
        success: true,
        message: 'Logged out successfully'
      });
      
    } catch (error) {
      request.log.error(error);
      
      // 即使登出失败也清除 cookie
      reply.clearCookie('refreshToken');
      
      reply.send({
        success: true,
        message: 'Logged out successfully'
      });
    }
  }
  
  // 获取当前用户信息
  async getProfile(request, reply) {
    try {
      const userId = request.user.id;
      
      const result = await authService.getSessionInfo(userId);
      
      reply.send({
        success: true,
        data: result,
        message: 'Profile retrieved successfully'
      });
      
    } catch (error) {
      request.log.error(error);
      
      reply.code(500).send({
        success: false,
        message: 'Failed to retrieve profile'
      });
    }
  }
  
  // 验证令牌
  async validateToken(request, reply) {
    try {
      const token = request.headers.authorization?.replace('Bearer ', '');
      
      if (!token) {
        return reply.code(400).send({
          success: false,
          message: 'Token required'
        });
      }
      
      const result = await authService.validateToken(token);
      
      reply.send({
        success: true,
        data: result,
        message: 'Token is valid'
      });
      
    } catch (error) {
      request.log.error(error);
      
      reply.code(401).send({
        success: false,
        message: 'Invalid token'
      });
    }
  }
  
  // 重新发送验证邮件
  async resendVerificationEmail(request, reply) {
    try {
      const { email } = request.body;
      const tenantId = request.tenantId;
      
      if (!email) {
        return reply.code(400).send({
          success: false,
          message: 'Email is required'
        });
      }
      
      if (!tenantId) {
        return reply.code(400).send({
          success: false,
          message: 'Tenant context required'
        });
      }
      
      await authService.resendVerificationEmail(email, tenantId);
      
      reply.send({
        success: true,
        message: 'Verification email sent'
      });
      
    } catch (error) {
      request.log.error(error);
      
      // 为了安全，即使用户不存在也返回成功消息
      reply.send({
        success: true,
        message: 'Verification email sent'
      });
    }
  }
}

module.exports = new AuthController();